package com.mimo.common.logic.code;

import com.mimo.common.result.BaseResult;
import com.mimo.common.rpc.proto.BaseResponseProto.BaseResponse;

/**
 * 用于定义logic模块返回给个调用者的状态码信息（包括业务异常编码）
 *
 * @author Hongyu
 */
public enum StatusCode {

  /*************** 系统 ***************/
  // 响应正常
  Success(0, ""),
  // 未知错误
  Error(-1, "UNKNOW ERROR"),

  /************* 用户模块 ***************/
  // 登陆授权失败
  LoginFailed(1000, "Login Failed"),
  // 用户被封禁
  UserBlocked(1001, "User Blocked"),
  // 点对点消息时,目标用户不存在
  InvalidPeer(1002, "Invalid Peer"),
  // 当前用户在其他移动设备上登录，此设备被踢下线
  ForceLogout(1003, "Force Logout"),
  // 当前用户不在线
  UserUnavailable(1004, "User Unavailable"),

  /******************* 消息模块 ******************/
  // 私信发送时，被拒绝接收
  P2PMessageReject(4000, "P2P Message Reject"),

  // 一般来说，正常用户是不会发生的，主要是防止恶意狂刷消息（点对点和房间消息）
  PersonMessageCap(4001, "User Message Too Many"),

  // 一般来说，聊天室的上行消息过多, 主要也是防止恶意狂刷消息（房间消息）
  RoomMessageCap(4002, "Room Upstream Message Too Many"),

  /**************** 聊天室 **********************/
  // 聊天室不存在
  RoomNotExist(2000, "Room Not Exist"),
  // 加入聊天时，聊天室成员超限
  RoomMemberCap(2001, "Reach The Room Cap"),
  // 当前用户在聊天室中已被禁言
  RoomMemberMute(2002, "Room Member Mute"),
  // 当前用户已被踢出并禁止加入聊天室
  RoomMemberKickoff(2003, "Room Member Kickoff"),
  // 尚未加入聊天室
  RoomUncheckIn(2004, "Room Un-CheckIn"),

  /******************* 服务间通讯时 *******************/
  CometUserUnlocated(3000, "User Unlocated Current Server");

  private static final BaseResponse SUCCESSFUL = BaseResponse.getDefaultInstance();

  final int code;
  final String msg;

  StatusCode(int code, String msg) {
    this.code = code;
    this.msg = msg;
  }

  public boolean isSuccess() {
    return this.code == 0;
  }

  public int getCode() {
    return code;
  }

  public String getMsg() {
    return msg;
  }

  // 直接转化为对外API的响应结果
  public BaseResult toBaseResult() {
    return new BaseResult(this.getCode(), this.getMsg());
  }

  public static StatusCode from(BaseResponse resp) {
    StatusCode code = null;
    for (StatusCode tmp : StatusCode.values()) {
      if (tmp.code == resp.getCode()) {
        code = tmp;
        break;
      }
    }
    return code;
  }

  public static boolean isSuccess(BaseResponse resp) {
    return resp.getCode() == 0;
  }

  public static BaseResponse getSuccessInstance() {
    return SUCCESSFUL;
  }

  public BaseResponse.Builder toBuilder() {
    return BaseResponse.newBuilder().setCode(this.code).setMsg(this.msg);
  }

  public BaseResponse toResp() {
    return this.toBuilder().build();
  }
}
